﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;
using Microsoft.Office.Core;
using Newtonsoft.Json;

namespace ExcelJsonParser
{
    class JsonWorkApp
    {
        private Application _excelApp = null;
        private JsonWorkBooks _jsonWorkBooks = null;
        private Range _currentCell;
        private CommandBarButton parseJsonButton;
        private static JsonWorkApp _jsonWorkApp;
        public Application ExcelApp { get { return _excelApp; } }

        public void SetExcelApp(Application excelApp)
        {
            _excelApp = excelApp;
        }
        public JsonViewWorkBook GetJsonViewWorkBook()
        {
            return _jsonWorkBooks.JsonViewWorkBook;
        }

        private JsonWorkApp()
        {
        }

        private JsonWorkApp(Application excelApp)
        {
            SetExcelApp(excelApp);
            _jsonWorkBooks = new JsonWorkBooks(excelApp.Workbooks);
            ((AppEvents_Event)_excelApp).NewWorkbook += new AppEvents_NewWorkbookEventHandler(JsonWorkApp_NewWorkbook);
            _excelApp.WorkbookOpen += new AppEvents_WorkbookOpenEventHandler(_excelApp_WorkbookOpen);
            ResetContextMenu();
        }

        void JsonWorkApp_NewWorkbook(Workbook Wb)
        {
            _jsonWorkBooks.Add(Wb);
            ws_SelectionChange(_excelApp.ActiveCell);
        }

        public static event onSelectionChanged SelectionChanged;
        public delegate void onSelectionChanged(Range Target); 

        internal void ws_SelectionChange(Range Target)
        {
            if (SelectionChanged != null)
            {
                SelectionChanged(Target);
            }
            if (Target.Rows.Count == 1 && Target.Columns.Count == 1)
            {
                object jsObject = JsonWorkCell.GetJsonValueFromCell(Target);
                if (jsObject is JavaScriptArray || jsObject is JavaScriptObject)
                {
                    _currentCell = Target;

                    AddMaintainJsonButton2ContextMenu();
                    return;
                }
            }
            _currentCell = null;
            ResetContextMenu();
        }

        void _excelApp_WorkbookOpen(Workbook Wb)
        {
            _jsonWorkBooks.Add(Wb);
            ws_SelectionChange(_excelApp.ActiveCell);
        }

        public static JsonWorkApp GetInstance()
        {
            if (_jsonWorkApp == null)
            {
                _jsonWorkApp = new JsonWorkApp();
            }
            return _jsonWorkApp;
        }

        public static JsonWorkApp InitJsonWorkApp(Application excelApp)
        {
            _jsonWorkApp = new JsonWorkApp(excelApp);
            return _jsonWorkApp;
        }

        void AddMaintainJsonButton2ContextMenu()
        {
            CommandBar rightClickMenu = ExcelApp.CommandBars["List Range Popup"];
            rightClickMenu.Reset();
            parseJsonButton = rightClickMenu.Controls.Add(MsoControlType.msoControlButton, Type.Missing, Type.Missing, Type.Missing, Type.Missing) as CommandBarButton;
            parseJsonButton.Move(rightClickMenu, 1);
            rightClickMenu.Controls[2].BeginGroup = true;
            parseJsonButton.Tag = "MaintainJson";
            parseJsonButton.Caption = "Maintain Json";
            parseJsonButton.BeginGroup = true;
            parseJsonButton.FaceId = 0163;
            parseJsonButton.Style = Microsoft.Office.Core.MsoButtonStyle.msoButtonCaption;
            parseJsonButton.Visible = true;
            parseJsonButton.Click += new _CommandBarButtonEvents_ClickEventHandler(parseJsonButton_Click);
        }

        void parseJsonButton_Click(CommandBarButton Ctrl, ref bool CancelDefault)
        {
            this.GetJsonViewWorkBook().ParseJsonCell(_currentCell);
        }

        void ResetContextMenu()
        {
            CommandBar rightClickMenu = ExcelApp.CommandBars["List Range Popup"];
            rightClickMenu.Reset();
        }

        public void ImportJsonString(string jsonString)
        {
            object javaObject = JavaScriptConvert.DeserializeObject(jsonString);
            JsonWorkBook jsonWb = null;
            if (_jsonWorkBooks.TryGetByName(this._excelApp.ActiveWorkbook.Name, out jsonWb))
            {
                jsonWb.ImportJson(javaObject);
            }
        }

        internal string ExportCurrentWorkSheet()
        {
            JsonWorkBook jsonWb = null;
            _jsonWorkBooks.TryGetByName(this._excelApp.ActiveWorkbook.Name, out jsonWb);
            object javaObject = jsonWb.ExportCurrentWorkSheet();
            return JavaScriptConvert.SerializeObject(javaObject);
        }

        internal string ExportCurrentWorkBook()
        {
            JsonWorkBook jsonWb = null;
            _jsonWorkBooks.TryGetByName(this._excelApp.ActiveWorkbook.Name, out jsonWb);
            object javaObject = jsonWb.ExportCurrentWorkBook();
            return JavaScriptConvert.SerializeObject(javaObject);
        }

        internal void ImportJsonStringIntoCurrentWorkSheet(string jsonString)
        {
            object javaObject = JavaScriptConvert.DeserializeObject(jsonString);
            JsonWorkBook jsonWb = null;
            if (_jsonWorkBooks.TryGetByName(this._excelApp.ActiveWorkbook.Name, out jsonWb))
            {
                jsonWb.ImportJson2CurrentWorkSheet(javaObject);
            }
        }

        internal void ConvertSelectedCell(object p)
        {
            JsonWorkBook jsonWb = null;
            JsonWorkCell.ConvertJsonValueTypeOfCell(_excelApp.ActiveCell, p);
            if (_jsonWorkBooks.TryGetByName(this._excelApp.ActiveWorkbook.Name, out jsonWb))
            {
                Worksheet ws = (Worksheet)_excelApp.ActiveSheet;
                JsonWorkSheet jsonWs = null;
                jsonWb.JsonWorkSheets.TryGetWorkSheetByName(ws.Name, out jsonWs);
                jsonWs.JsonWorkSheetTable.RefreshCell(_excelApp.ActiveCell);
            }
            JsonWorkApp.SelectionChanged(_excelApp.ActiveCell);
        }
    }
}
